import asyncio
from concurrent.futures import ThreadPoolExecutor
import time
import random

"""
使用场景：当主体代码是使用协程异步，需要与多进程或多线程代码对接时。(如：与不支持asyncio的mysql的api对象对接；还有request  )
run_in_executor：
1. Run in the default loop's executor( &iThreadPoolExecutor ) 
2. Run in a custom process poo1:
# with concurrent.futures.ProcessPoolExecutor() as pool:
    result = await loop.run_in_executor(pool, func1)print('custom process pool', result)
第一步:内部会先调用 ThreadPoolExecutor 的 submit 方法去线程池中申请一个线程去执行func1函数，并返同一个concurrent.futures.Future对象
第二步:调用asyncio.wrap_future将concurrent,futures.Future对象包装为-->asycio,Future对象#因为concurrent,futures,Future对象不支持await语法，所以需要包装为 asycio.Future对象 才能使用,
"""
"""
# 创建线程池
thread_pool = ThreadPoolExecutor(max_workers=10)


def task(num):
    time.sleep(5)
    print("handling {}".format(num))


async def async_task(task_id):
    # 模拟一个异步任务
    print(f"开始执行任务 {task_id}")
    # 使用线程池执行耗时操作
    await asyncio.get_event_loop().run_in_executor(
        thread_pool,
        task,
        task_id
    )
    print(f"任务 {task_id} 执行完成")
    return f"任务 {task_id} 的结果"


async def main():
    # 创建多个任务
    tasks = [async_task(i) for i in range(10)]

    # 异步执行所有任务
    results = await asyncio.gather(*tasks)

    # 打印结果
    for result in results:
        print(result)

if __name__ == "__main__":
    asyncio.run(main())
"""
import os
import requests
from concurrent.futures import ThreadPoolExecutor


def download(file_path, url):
    res = requests.get(
        url=url,
        headers={
            "User-Agent": "Nozilla/5"
        })

    with open(file_path, mode='wb') as img_object:
        img_object.write(res.content)


thread_pool = ThreadPoolExecutor(max_workers=10)


def task(num):
    time.sleep(5)
    print("handling {}".format(num))


async def async_task(index, url):
    # 模拟一个异步任务
    print(f"开始执行任务 {url}")
    # 创建线程池，最多维护18个线程。
    if not os.path.exists("images"):
        os.makedirs("images")
    file_name = "{}.png".format(index)
    file_path = os.path.join("images", file_name)
    # 使用线程池执行耗时操作
    await asyncio.get_event_loop().run_in_executor(
        thread_pool,
        download,
        file_path, url
    )
    print(f"任务 {url} 执行完成")
    return f"任务 {url} 的结果"



async def main():
    file_object = [
        "https://preview.qiantucdn.com/agency/dp/dp_thumbs/1028635/7037540/staff_1024.jpg%21kuan320_webp",
        "https://preview.qiantucdn.com/58pic/LN/hy/85/CQ/va1rfw6nj5g7i8h3zcm4odtlqx0pyu9e_PIC2018.png%21qt324new_nowater"
    ]
    # 创建多个任务
    tasks = [async_task(i, url) for i, url in enumerate(file_object)]
    # 异步执行所有任务
    results = await asyncio.gather(*tasks)
    # 打印结果
    for result in results:
        print(result)


if __name__ == "__main__":
    asyncio.run(main())  # main函数中有大的或小的wait
    # # 或
    # file_object = [
    #     "https://preview.qiantucdn.com/agency/dp/dp_thumbs/1028635/7037540/staff_1024.jpg%21kuan320_webp",
    #     "https://preview.qiantucdn.com/58pic/LN/hy/85/CQ/va1rfw6nj5g7i8h3zcm4odtlqx0pyu9e_PIC2018.png%21qt324new_nowater"
    # ]
    # # 创建多个任务
    # tasks = [async_task(i, url) for i, url in enumerate(file_object)]
    # asyncio.run(asyncio.wait(tasks))

